package com.duan.laugh.common.gateway.config;

import cn.hutool.core.util.ObjectUtil;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import lombok.extern.slf4j.Slf4j;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.List;

/**
 * @author duanjw
 */
@Slf4j
public class LocalRule extends ZoneAvoidanceRule {
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }

    public Server choose(ILoadBalancer lb, Object key) {

        // 本机ip
        String hostIp = getHostIp();
        final List<Server> serverList = lb.getAllServers();
        Server localhostServer = null;
        for (Server server : serverList) {
            String host = server.getHost();

            // 1. 优先使用请求客户端的ip对应的服务
            if (ObjectUtil.equal(key, host)) {
                log.debug("【{}】有注册此服务，使用【{}】对应的服务", key, key);
                return server;
            }
            // 本机的服务
            if (ObjectUtil.equal(hostIp, host)) {
                localhostServer = server;
            }
        }
        // 2. 其次使用本机的服务
        if (null != localhostServer) {
            log.debug("请求的客户端没有此服务，但是本机有此服务，使用本机对应的服务");
            return localhostServer;
        }
        return super.choose(key);
    }

    private static String getHostIp() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress ip = (InetAddress) addresses.nextElement();
                    if (ip != null
                            && ip instanceof Inet4Address
                            && !ip.isLoopbackAddress() //loopback地址即本机地址，IPv4的loopback范围是127.0.0.0 ~ 127.255.255.255
                            && ip.getHostAddress().indexOf(":") == -1) {
                        return ip.getHostAddress();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
